package top.v5it.japi.plus.support.limit;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import top.v5it.japi.plus.support.LuaScriptUtil;

import java.util.Collections;

/**
 * 基于滑动窗口限流，在一个滑动窗口周期内只允许n个流量进入
 *
 * @author zhanpu
 * @date 2022/5/23
 */
@Slf4j
@RequiredArgsConstructor
public class JapiLimitWithWindowHandler implements JapiLimitHandler {

    private final String cachePrefix;
    private final RedisTemplate<String, Object> redisTemplate;

    /**
     * 限流处理
     *
     * @param limit    限制大小
     * @param time     时间
     * @param limitKey key
     * @return 当前限制数
     * @throws FrequencyLimitedException {@link FrequencyLimitedException} 超出限流异常
     */
    @Override
    public Long handler(String limitKey, String limit, String time) {
        limitKey = cachePrefix + ":" + limitKey;

        // 没有指定序列化方式，默认使用上面配置的
        return redisTemplate.execute(LuaScriptUtil.getLuaLimitWithWindowScript()
                , Collections.singletonList(limitKey)
                , limit
                , time
                , Long.toString(System.currentTimeMillis())
        );
    }
}
